
#ifndef variant_vector_h
#define variant_vector_h

//#if Windows
//
//#include <vector>
//
//#else

typedef unsigned int size_t;

namespace std
{

	// http://stackoverflow.com/questions/5159061/implementation-of-vector-in-c
	template <class T> class  vector2
	{
	public:

		typedef T * iterator;

		vector2();
		vector2(unsigned int size);
		vector2(unsigned int size, const T & initial);
		vector2(const vector2<T> & v);      
		~vector2();

		unsigned int capacity() const;
		unsigned int size() const;
		bool empty() const;
		iterator begin();
		iterator end();
		T & front();
		T & back();
		void push_back(const T & value); 
		void pop_back();  

		void reserve(unsigned int capacity);   
		void resize(unsigned int size);   
		void resize(unsigned int size, T defaultValue);   

		void insert(iterator where, const T* first, const T* last);
		
		T & operator[](unsigned int index);  
		T & operator[](unsigned int index) const;  
		T & at(unsigned int index);  
		vector2<T> & operator=(const vector2<T> &);
		void clear();
		void erase(iterator value);
	private:
		unsigned int my_size;
		unsigned int my_capacity;
		T * buffer;
	};

	// Your code goes here ...
	template<class T>
	vector2<T>::vector2()
	{
		my_capacity = 0;
		my_size = 0;
		buffer = 0;
	}

	template<class T>
	vector2<T>::vector2(const vector2<T> & v)
	{
		my_size = v.my_size;
		my_capacity = v.my_capacity;
		buffer = new T[my_size];  
		for (unsigned int i = 0; i < my_size; i++)
			buffer[i] = v.buffer[i];  
	}

	template<class T>
	vector2<T>::vector2(unsigned int size)
	{
		my_capacity = size;
		my_size = size;
		buffer = new T[size];
	}

	template<class T>
	vector2<T>::vector2(unsigned int size, const T & initial)
	{
		my_size = size;
		my_capacity = size;
		buffer = new T [size];
		for (unsigned int i = 0; i < size; i++)
			buffer[i] = initial;
		//T();
	}

	template<class T>
	vector2<T> & vector2<T>::operator = (const vector2<T> & v)
	{
		delete[ ] buffer;
		my_size = v.my_size;
		my_capacity = v.my_capacity;
		buffer = new T [my_size];
		for (unsigned int i = 0; i < my_size; i++)
			buffer[i] = v.buffer[i];
		return *this;
	}

	template<class T>
	typename vector2<T>::iterator vector2<T>::begin()
	{
		return buffer;
	}

	template<class T>
	typename vector2<T>::iterator vector2<T>::end()
	{
		return buffer + size();
	}

	template<class T>
	T& vector2<T>::front()
	{
		return buffer[0];
	}

	template<class T>
	T& vector2<T>::back()
	{
		return buffer[size - 1];
	}

	template<class T>
	void vector2<T>::push_back(const T & v)
	{
		if (my_size >= my_capacity)
			reserve(my_capacity + (unsigned int)(my_capacity * 0.5) + 2);
		buffer [my_size++] = v;
	}

	template<class T>
	void vector2<T>::pop_back()
	{
		my_size--;
	}

	template<class T>
	void vector2<T>::reserve(unsigned int capacity)
	{
		if(buffer == 0)
		{
			my_size = 0;
			my_capacity = 0;
		}    
		T * Newbuffer = new T [capacity];

		unsigned int l_Size = capacity < my_size ? capacity : my_size;

		for (unsigned int i = 0; i < l_Size; i++)
			Newbuffer[i] = buffer[i];

		my_capacity = capacity;
		delete[] buffer;
		buffer = Newbuffer;
	}

	template<class T>
	unsigned int vector2<T>::size()const//
	{
		return my_size;
	}

	template<class T>
	bool vector2<T>::empty()const//
	{
		return (my_size == 0);
	}
	
	template<class T>
	void vector2<T>::resize(unsigned int size)
	{
		reserve(size);
		my_size = size;
	}
	
	template<class T>
	void vector2<T>::resize(unsigned int size, T defaultValue)
	{
		unsigned int oldSize = my_size;
		reserve(size);
		my_size = size;

		for (unsigned int i = oldSize; i < my_size; i++)
		{
			buffer[i] = defaultValue;
		}
	}

	template<class T>
	void vector2<T>::insert(iterator where, const T* first, const T* last)
	{
		vector2<T> A;

		// Get all before where.
		unsigned int i = 0;
		for (i = 0; i < my_size; i++)
		{
			if(&buffer[i] == where)
				break;
			A.push_back(buffer[i]);
		}

		// Insert the middle.
		while(first != last)
		{
			A.push_back(*first);
			first++;
		}

		// Get the last.
		for (; i < my_size; i++)
		{
			A.push_back(buffer[i]);
		}

		clear();
		for (i = 0; i < A.size(); i++)
		{
			push_back(A[i]);
		}

		//return (begin() + _Off);
	}
	
	template<class T>
	T& vector2<T>::operator[](unsigned int index)
	{
		return buffer[index];
	}  

	template<class T>
	T& vector2<T>::operator[](unsigned int index) const
	{
		return buffer[index];
	}  

	template<class T>
	T& vector2<T>::at(unsigned int index)
	{
		return buffer[index];
	}  

	template<class T>
	unsigned int vector2<T>::capacity()const
	{
		return my_capacity;
	}

	template<class T>
	vector2<T>::~vector2()
	{
		delete[ ] buffer;
	}
	template <class T>
	void vector2<T>::clear()
	{
		my_capacity = 0;
		my_size = 0;
		buffer = 0;
	}
	template <class T>
	void vector2<T>::erase(iterator value)
	{
		unsigned int removed(0);
		for (unsigned int i = 0; i < my_size - removed; i++)
		{
			if(buffer[i] == *value)
			{
				removed = 1;
			}

			if(removed == 1)
			{
				buffer[i] = buffer[i+1];
			}
		}

		if(removed == 1)
		{
			my_size--;
		}
	}
}

//#endif

#endif